<template>
  <div
    ref="tableBoxRef"
    class="public-table-content">
    <el-table
      ref="publicTable"
      :data="tableData.tbodyData"
      :border="border"
      :stripe="stripe"
      :max-height="maxHeight"
      class="pubilc-table-style">
      <el-table-column
        v-if="isMultiple"
        align="center"
        type="selection"
        width="45" />
      <el-table-column
        v-if="showIndex"
        align="center"
        type="index"
        width="50"
        label="序号" />
      <template v-for="(tItem, index) in tableData.tHeadData">
        <el-table-column
          :key="`${tItem.prop} - ${index}`"
          :prop="tItem.prop"
          :label="tItem.name"
          :fixed="tItem.fixed"
          :min-width="tItem.width"
          :show-overflow-tooltip="tItem.showTip">
          <template slot="header">
            <span v-html="renderHead(tItem)" />
          </template>
          <template slot-scope="scope">
            <el-image
              v-if="tItem.isImg"
              style="width: 50px; height: 50px"
              fit="fill"
              :src="handleImageData(scope.row[tItem.prop])"
              :preview-src-list="handlePreviewSrcData(scope.row[tItem.prop])" />
            <el-link
              v-else-if="tItem.isUrl"
              :href="scope.row[tItem.prop]"
              target="_blank">
              {{ scope.row[tItem.prop] }}
            </el-link>
            <span
              v-else
              v-html="renderBody(scope.row, tItem)" />
            &nbsp;
            <el-tooltip
              v-if="showBodyTip(scope.row, tItem, 'bol')"
              :content="showBodyTip(scope.row, tItem, 'text')"
              placement="top"
              style="cursor: pointer;">
              <i :class="showBodyTip(scope.row, tItem, 'icon')" />
            </el-tooltip>
          </template>
        </el-table-column>
      </template>
      <template v-for="(operaObj, idx) in operaList">
        <el-table-column
          v-if="jsonClone(operaObj) !== '{}'"
          :key="`${operaObj.width}-${idx}`"
          :fixed="operaObj.fixed"
          :label="operaObj.label"
          :min-width="operaObj.width">
          <template slot-scope="scope">
            <template
              v-for="(opera, index) in operaObj.list">
              <el-switch
                v-if="opera.type === 'switch'"
                :key="`${index}-switch`"
                v-model="scope.row[opera.tag]"
                :active-value="opera['active']"
                :inactive-value="opera['inactive']"
                :disabled="disSwitch(scope.row)"
                @change="handleSwitch($event, scope.row)" />
              <span
                v-if="opera.type === 'btn' && showBtn(scope.row, opera.value)"
                :key="`${index}-${opera.label}`"
                class="span-btn"
                :style="[changeColor(opera.color)]"
                @click="handleOpera(scope.row, opera.value, scope)">
                {{ opera.label }}
              </span>
            </template>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <!-- 分页器 -->
    <div
      v-if="tableTotal !== 0 && showPagination"
      ref="pagination"
      class="pagination-container">
      <el-pagination
        background
        :current-page.sync="pageNum"
        :page-size.sync="pageSize"
        :layout="setLayout || 'total, sizes, prev, pager, next, jumper'"
        :page-sizes="[10, 20, 30, 50]"
        :total="tableTotal"
        @size-change="handlePageSize"
        @current-change="handlePageNum" />
    </div>
  </div>
</template>

<script>
import { getTHead, getTOpera } from '@/utils/tableConfig';

export default {
  // name: 'PublicTable',
  inheritAttrs: false,
  props: {
    /** 表格数据 */
    tData: {
      type: Array,
      default: () => []
    },
    /** 数据总数 */
    tableTotal: {
      type: Number,
      default: 0
    },
    /** 当前页面 */
    currentPage: {
      type: String,
      default: ''
    },
    /** 额外参数 */
    extraParam: {
      type: null,
      default: null
    },
    /** 是否展示分页器 */
    showPagination: {
      type: Boolean,
      default: true
    },
    /** 分页器 */
    pagination: {
      type: Object,
      default: () => {
        return {
          pageNum: 1,
          pageSize: 20
        };
      }
    },
    /** 分页器布局 */
    setLayout: {
      type: String,
      default: ''
    },
    /** 表格最大高度 */
    offsetHeight: {
      type: String,
      default: ''
    },
    /** 是否可选 */
    isMultiple: {
      type: Boolean,
      default: false
    },
    /** 是否需要纵向边框 */
    border: {
      type: Boolean,
      default: true
    },
    /** 是否需要斑马纹 */
    stripe: {
      type: Boolean,
      default: false
    },
    /** 是否展示序号 */
    showIndex: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 表格数据
      tableData: {
        tHeadData: [],
        tbodyData: []
      },
      // 表格高
      maxHeight: 0,
      // 操作列
      operaList: [],
      // 分页器当前页
      pageNum: 1,
      // 分页器一页显示多少条
      pageSize: 20
    };
  },
  watch: {
    tData: {
      handler(val) {
        this.tableData.tbodyData = val;
        this.pageNum = this.pagination.pageNum;
        this.pageSize = this.pagination.pageSize;
        this.tableData.tHeadData = getTHead(this.currentPage, this.extraParam);
        this.operaList = getTOpera(this.currentPage, this.extraParam);
      },
      deep: true
    }
  },
  mounted() {
    this.resetHeight();
    window.addEventListener('resize', this.resetHeight);
  },
  beforeUpdate() {
    this.$nextTick(() => {
      this.$refs.publicTable.doLayout();
    });
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resetHeight);
  },
  methods: {
    /**
     * 获取高度
     * @param {undefined} 无
     * @returns {undefined} 无
     */
    resetHeight() {
      this.$nextTick(() => {
        this.maxHeight = this.$refs.tableBoxRef['offsetHeight'];
        if (this.$refs.pagination && this.$refs.pagination['offsetHeight']) {
          this.maxHeight = this.$refs.tableBoxRef['offsetHeight'] -
            (this.$refs.pagination['offsetHeight'] || 0);
        }
        if (this.offsetHeight) {
          this.maxHeight = this.offsetHeight;
        }
      });
    },

    /**
     * 渲染表头
     * @param {obj} tItem 表头数据
     * @returns {json} 格式化数据
     */
    renderHead(tItem) {
      const str = tItem.name;
      return str;
    },

    /**
     * 渲染表体
     * @param {obj} row 表体数据
     * @param {obj} tItem 表头数据
     * @returns {json} 格式化数据
     */
    renderBody(row, tItem) {
      // const page = this.currentPage;
      const prop = this.jsonClone(tItem.prop);
      const rowData = this.jsonClone(row[prop]);
      const html = rowData;
      if (!html && html !== 0) return '';
      return html;
    },

    /**
     * 渲染图标tooltip
     * @param {obj} row 表体数据
     * @param {obj} tItem 表头数据
     * @param {str} icon 图标类型
     * @returns {json} 格式化数据
     */
    showBodyTip(row, tItem, str) {
      // const page = this.currentPage;
      // const prop = tItem.prop;
      return null;
    },

    /**
     * 更改文字样式
     * @param {str} color 样式
     * @returns {obj} 样式对象
     */
    changeColor(color) {
      return {
        '--color-font': color
      };
    },

    /**
     * 点击操作
     * @param {obj} row 行数据
     * @param {str} type 点击按钮类型
     * @param {str} val 其它参数
     * @returns {undefined} 无
     */
    handleOpera(row, type, val) {
      // const page = this.currentPage;
      const flag = true;
      if (!flag) return;
      this.$emit('clickOperaBtn', row, type, val);
    },

    /**
     * 切换switch
     * @param {str} val 切换值
     * @param {obj} item 表格行数据
     * @returns {undefined} 无
     */
    handleSwitch(val, item) {
      this.$emit('clickSwitch', val, item);
    },

    /**
     * 禁用switch
     * @param {obj} row 行数据
     * @returns {undefined} 无
     */
    disSwitch(row) {
      const flag = false;
      // const page = this.currentPage;
      return flag;
    },

    /**
     * 修改页码
     * @param {underfind} 无
     * @returns {underfind} 无
     */
    handlePageNum(val) {
      this.$emit('changePagination', { pageNum: val, pageSize: this.pageSize });
    },

    /**
     * 修改页容量
     * @param {underfind} 无
     * @returns {underfind} 无
     */
    handlePageSize(val) {
      if (this.pageNum * val > this.tableTotal) {
        this.pageNum = 1;
      }
      this.$emit('changePagination', { pageNum: this.pageNum, pageSize: val });
    },

    /**
     * 判断该展示的标签
     * @param {obj} item 表格行数据
     * @param {str} key 按钮代表值
     * @returns {undefined} 无
     */
    showBtn(item, key) {
      const page = this.currentPage;
      if (page === 'poi-list') {
        if (key === 'check') {
          return item.latitude &&
        item.longitude && item.poiType !== 1;
        }
      }
      return true;
    },
    /*
     * @description: 处理Table列为图片的数据
     * @author: liaoy
     * @date: 2023-03-28 12:07:35
     * @params1: 数组或字符串
     * @return: 字符串
     */
    handleImageData(data) {
      if (data instanceof Array) {
        return data[0];
      }
      return data;
    },
    /*
     * @description:处理预览的数据
     * @author: liaoy
     * @date: 2023-03-28 12:10:40
     * @params1: 字符串或数组
     * @return: array
     */
    handlePreviewSrcData(data) {
      if (data instanceof Array) {
        return data;
      }
      return [data];
    }
  }
};
</script>

<style lang="scss" scoped>
.public-table-content {
  height: 100%;
  text-align: center;

  .span-btn {
    cursor: pointer;
    display: inline-block;
    height: 28px;
    padding: 0 10px;
    margin-right: 12px;
    font-size: 14px;
    color: var(--color-font);
    line-height: 28px;
    text-align: center;
  }
}
</style>
